package pe.com.bbva.ge.vista.vaadin.ui.registrosolicitud;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.springframework.beans.factory.annotation.Autowired;

import pe.com.bbva.ge.domain.configuracion.Atm;
import pe.com.bbva.ge.domain.configuracion.Casetera;
import pe.com.bbva.ge.domain.configuracion.Denominacion;
import pe.com.bbva.ge.domain.configuracion.Lista;
import pe.com.bbva.ge.domain.configuracion.Posicion;
import pe.com.bbva.ge.domain.configuracion.TipoCasetera;
import pe.com.bbva.ge.domain.configuracion.Valor;
import pe.com.bbva.ge.domain.solicitud.Destino;
import pe.com.bbva.ge.domain.solicitud.DetalleCasetera;
import pe.com.bbva.ge.domain.solicitud.DetalleDenominacion;
import pe.com.bbva.ge.domain.solicitud.DetalleMoneda;
import pe.com.bbva.ge.negocio.ConfiguracionNegocio;
import pe.com.bbva.ge.vista.vaadin.ui.BaseUI;
import pe.com.bbva.ge.vista.vaadin.ui.utileria.AsignarDestino;
import pe.com.bbva.ge.vista.vaadin.ui.utileria.ManejadorDenominacion;
import pe.com.bbva.ge.vista.vaadin.ui.utileria.ManejadorDenominacion2;
import pe.com.bbva.ge.vista.vaadin.ui.utileria.ManejadorDivisa;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class RegistrarSolicitudDetalleUI extends BaseUI implements AsignarDestino {

	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private TabSheet tabDetalles;

	@AutoGenerated
	private VerticalLayout lytAtms;

	@AutoGenerated
	private Panel pnlAtms;

	@AutoGenerated
	private VerticalLayout lytPnlAtms;

	@AutoGenerated
	private HorizontalLayout hlytTotales;

	@AutoGenerated
	private GridLayout lytAtmsCasetera;

	@AutoGenerated
	private VerticalLayout lytDetalles;

	@AutoGenerated
	private Panel pnlDivisas;

	@AutoGenerated
	private VerticalLayout lytContenido;

	@AutoGenerated
	private HorizontalLayout lytCheckDivisas;

	/**
	 * 
	 */
	private static final long serialVersionUID = 5157786063928294339L;
	
	@Autowired
	private ConfiguracionNegocio genericoNegocio;
	
	private Posicion posicionDestino;
	
	private boolean mostrarDeteriorados;
	
	private Map<CheckBox, RegistrarSolicitudDivisaUI> mapDenominaciones;
	
	private Map<Valor, ManejadorDivisa> mapManejadorDivisa;
	
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public RegistrarSolicitudDetalleUI(Posicion posicionDestino) {
		buildMainLayout();
		setCompositionRoot(mainLayout);		
		this.posicionDestino = posicionDestino;
	}
	
	@Override
	public void postConstruccion() {
		mapDenominaciones = new HashMap<CheckBox, RegistrarSolicitudDivisaUI>();
		construirDetalleDenominaciones();		
		construirATMS();
		
	}

	private void construirDetalleDenominaciones() {
		List<Valor> divisas = genericoNegocio.obtenerValores(Lista.CODIGO.DIVISA);
		
		for (Valor divisa : divisas) {
			
			boolean mostrarDivisa = Valor.CODIGO.MONEDA_PEN.equals(divisa.getCodigo()) ||
					Valor.CODIGO.MONEDA_DOL.equals(divisa.getCodigo());
			
			final RegistrarSolicitudDivisaUI lytDenominacion = new RegistrarSolicitudDivisaUI();
			lytDenominacion.setDivisa(divisa);
			lytDenominacion.setMostrarDeteriorados(mostrarDeteriorados);
			lytDenominacion.setVisible(mostrarDivisa);
			lytContenido.addComponent(lytDenominacion);
			lytContenido.setComponentAlignment(lytDenominacion, new Alignment(6));
			
			final CheckBox chkDivisa = new CheckBox();
			chkDivisa.setData(divisa);
			chkDivisa.setCaption(divisa.getCodigo());
			chkDivisa.setImmediate(true);
			chkDivisa.setValue(mostrarDivisa);
			chkDivisa.setWidth("-1px");
			chkDivisa.setHeight("-1px");
			chkDivisa.addListener(new Property.ValueChangeListener() {
				@Override
				public void valueChange(ValueChangeEvent event) {
					lytDenominacion.setVisible((Boolean)chkDivisa.getValue());
				}
			});
			
			mapDenominaciones.put(chkDivisa, lytDenominacion);
			lytCheckDivisas.addComponent(chkDivisa);			
		}
	}

	private void construirATMS() {
		
		mapManejadorDivisa = new HashMap<Valor, ManejadorDivisa>();
		
		List<Casetera> caseteras = genericoNegocio.obtenerCaseterasPorProveedor(this.posicionDestino);
		
		Map<Valor, TextField[]> mpTxtTotales = new HashMap<Valor, TextField[]>();
		
		Set<TipoCasetera> tipoCaseteras = new TreeSet<TipoCasetera>();
		
		Set<Atm> atms = new TreeSet<Atm>();
		
		Map<String, Casetera> mCasetera = new HashMap<String, Casetera>();
		String separador = "_";
		for (Casetera casetera : caseteras) {
			tipoCaseteras.add(casetera.getTipo());
			atms.add(casetera.getAtm());
			StringBuilder strKey = new StringBuilder();
			strKey.append(casetera.getTipo().getCodigo());
			strKey.append(separador);
			strKey.append(casetera.getAtm().getCodigo());
			mCasetera.put(strKey.toString(), casetera);
		}
		
		int tamanhoColumnas = tipoCaseteras.size() + 1;
		int tamanhoFilas = atms.size() + 1;
		
		lytAtmsCasetera.setColumns(tamanhoColumnas);
		lytAtmsCasetera.setRows(tamanhoFilas);
		
		lytAtmsCasetera.setSpacing(false);
		
		Iterator<Atm> iAtm = atms.iterator();
		
		int atmCount = 1;
		while (iAtm.hasNext()) {
			Atm atm = iAtm.next();
			Label lblNombre = new Label();
			lblNombre.setData(atm.getCodigo());
			lblNombre.setValue(atm.getNombre());
			lytAtmsCasetera.addComponent(lblNombre, 0, atmCount);
			atmCount++;
		}
		
		int tipoCaseteraCount = 1;
		
		Iterator<TipoCasetera> iTipoCasetera = tipoCaseteras.iterator();
		while (iTipoCasetera.hasNext()) {
			TipoCasetera tipoCasetera = iTipoCasetera.next();
			Label lblCasetera = new Label();
			lblCasetera.setValue(tipoCasetera.getDenominacion().getValor());
			lblCasetera.setData(tipoCasetera);
			lytAtmsCasetera.addComponent(lblCasetera, tipoCaseteraCount, 0);
			tipoCaseteraCount++;
			
			if(!mpTxtTotales.containsKey(tipoCasetera.getDenominacion().getMoneda()))
			{
				mpTxtTotales.put(tipoCasetera.getDenominacion().getMoneda(), 
						buildTotalMoneda(tipoCasetera.getDenominacion().getMoneda()) );
			}
		}
		
		for (int i = 1; i < tamanhoColumnas; i++) {
			AbstractComponent acCasetera = (AbstractComponent) lytAtmsCasetera.getComponent(i, 0);//Casetera
			TipoCasetera tipoCasetera = (TipoCasetera) acCasetera.getData();
			
			if(!mapManejadorDivisa.containsKey(tipoCasetera.getDenominacion().getMoneda()))
			{
				
				if(mpTxtTotales.containsKey(tipoCasetera.getDenominacion().getMoneda()))
				{
					TextField[] txt = mpTxtTotales.get(tipoCasetera.getDenominacion().getMoneda());
					mapManejadorDivisa.put(tipoCasetera.getDenominacion().getMoneda(), new ManejadorDivisa(txt[0], txt[1]));
				}
			}
			
			ManejadorDivisa manejadorDivisa = mapManejadorDivisa.get(tipoCasetera.getDenominacion().getMoneda());
			manejadorDivisa.setModoCrear(true);
			
			String codigoCasetera = tipoCasetera.getCodigo();
			for (int j = 1; j < tamanhoFilas; j++) {
				AbstractComponent acAtm = (AbstractComponent) lytAtmsCasetera.getComponent(0, j);//Atm
				String codigoAtm = (String) acAtm.getData();
				
				StringBuilder strKey = new StringBuilder();
				strKey.append(codigoCasetera);
				strKey.append(separador);
				strKey.append(codigoAtm);
				
				if(mCasetera.containsKey(strKey.toString()))
				{
					ManejadorDenominacion2 manejadorDenominacion = new ManejadorDenominacion2(tipoCasetera.getDenominacion(), manejadorDivisa);
					manejadorDivisa.agregarManejadorDenominacion(tipoCasetera.getDenominacion(), manejadorDenominacion);
					lytAtmsCasetera.addComponent(
							buildCelda(mCasetera.get(strKey.toString()), 
									manejadorDenominacion), i, j);
				}
			}
		}
		
		lytPnlAtms.setSizeUndefined();
	}
	
	private TextField[] buildTotalMoneda(Valor divisa)
	{
		// lblDivisa
		Label lblDivisa = new Label();
		lblDivisa.setImmediate(false);
		lblDivisa.setWidth("-1px");
		lblDivisa.setHeight("-1px");
		lblDivisa.setValue("Total " + divisa.getNombre());
		hlytTotales.addComponent(lblDivisa);
		
		TextField[] textFields = new TextField[2];
		
		// txtTotal
		TextField txtTotal = new TextField();
		txtTotal.setWidth("-1px");
		txtTotal.setHeight("-1px");
		txtTotal.setEnabled(false);
		txtTotal.setInputPrompt("Total " + divisa.getNombre());
		hlytTotales.addComponent(txtTotal);
		
		textFields[0] = txtTotal;
		
		// txtDiferencial
		TextField txtDiferencial = new TextField();
		txtDiferencial.setWidth("-1px");
		txtDiferencial.setHeight("-1px");
		txtDiferencial.setEnabled(false);
		txtDiferencial.setInputPrompt("Restante " + divisa.getNombre());
		hlytTotales.addComponent(txtDiferencial);
		
		textFields[1] = txtDiferencial;
		
		return textFields;
	}
	
	private VerticalLayout buildCelda(Casetera casetera, ManejadorDenominacion2 manejadorDenominacion) {
		// common part: create layout
		VerticalLayout vlytAtmCasetera = new VerticalLayout();
		vlytAtmCasetera.setImmediate(false);
		vlytAtmCasetera.setWidth("170px");
		vlytAtmCasetera.setHeight("68px");
		vlytAtmCasetera.setMargin(false);
		vlytAtmCasetera.setData(casetera);
		
		// hlytAtmCasetera1
		HorizontalLayout hlytTotales = buildHlytTotalesCasetera(manejadorDenominacion);
		vlytAtmCasetera.addComponent(hlytTotales);
		
		// hlytAtmCasetera1
		HorizontalLayout hlytAtmCasetera1 = buildHlytAtmCasetera1(manejadorDenominacion);
		vlytAtmCasetera.addComponent(hlytAtmCasetera1);
		
		// hlytAtmCasetera2
		HorizontalLayout hlytAtmCasetera2 = buildHlytAtmCasetera2();
		vlytAtmCasetera.addComponent(hlytAtmCasetera2);
		vlytAtmCasetera.setExpandRatio(hlytAtmCasetera2, 1.0f);
		
		return vlytAtmCasetera;
	}

	private HorizontalLayout buildHlytTotalesCasetera(ManejadorDenominacion2 manejadorDenominacion) {
		HorizontalLayout hlytTotales = new HorizontalLayout();
		hlytTotales.setImmediate(false);
		hlytTotales.setWidth("160px");
		hlytTotales.setHeight("-1px");
		hlytTotales.setMargin(false);
		
		// txtTotal
		TextField txtTotal = new TextField();
		txtTotal.setImmediate(false);
		txtTotal.setWidth("160px");
		txtTotal.setHeight("-1px");
		txtTotal.setInputPrompt("Total");
		txtTotal.setEnabled(false);
		hlytTotales.addComponent(txtTotal);		
		
		manejadorDenominacion.setTxtTotalDenominacion(txtTotal);
		
		return hlytTotales;
	}

	private HorizontalLayout buildHlytAtmCasetera1(ManejadorDenominacion2 manejadorDenominacion) {
		// common part: create layout
		HorizontalLayout hlytAtmCasetera1 = new HorizontalLayout();
		hlytAtmCasetera1.setImmediate(false);
		hlytAtmCasetera1.setWidth("160px");
		hlytAtmCasetera1.setHeight("-1px");
		hlytAtmCasetera1.setMargin(false);
		hlytAtmCasetera1.setData(manejadorDenominacion);
		
		// txtCantidad
		TextField txtCantidad = new TextField();
		txtCantidad.setImmediate(false);
		txtCantidad.setWidth("79px");
		txtCantidad.setHeight("-1px");
		txtCantidad.setInputPrompt("Cantidad");
		//txtCantidad.setSecret(false);
		hlytAtmCasetera1.addComponent(txtCantidad);
		
		manejadorDenominacion.setTxtCantidad(txtCantidad);
		
		// txtImporte
		TextField txtImporte = new TextField();
		txtImporte.setImmediate(false);
		txtImporte.setWidth("79px");
		txtImporte.setHeight("-1px");
		txtImporte.setInputPrompt("Importe");
		//txtImporte.setSecret(false);
		hlytAtmCasetera1.addComponent(txtImporte);
		
		manejadorDenominacion.setTxtImporte(txtImporte);
		
		return hlytAtmCasetera1;
	}

	private HorizontalLayout buildHlytAtmCasetera2() {
		// common part: create layout
		HorizontalLayout hlytAtmCasetera2 = new HorizontalLayout();
		hlytAtmCasetera2.setImmediate(false);
		hlytAtmCasetera2.setWidth("160px");
		hlytAtmCasetera2.setHeight("-1px");
		hlytAtmCasetera2.setMargin(false);
		
		// txtObservacion
		TextArea txtObservacion = new TextArea();
		txtObservacion.setImmediate(false);
		txtObservacion.setWidth("158px");
		txtObservacion.setHeight("46px");
		txtObservacion.setInputPrompt("Observación");
		hlytAtmCasetera2.addComponent(txtObservacion);
		//hlytAtmCasetera2.setExpandRatio(txtObservacion, 1.0f);
		
		return hlytAtmCasetera2;
	}

	public boolean isMostrarDeteriorados() {
		return mostrarDeteriorados;
	}

	public void setMostrarDeteriorados(boolean mostrarDeteriorados) {
		this.mostrarDeteriorados = mostrarDeteriorados;
	}
	
	@Override
	public void asignarDestino(Destino destino) {
		
		Iterator<CheckBox> chkDivisas = mapDenominaciones.keySet().iterator();
		while(chkDivisas.hasNext())
		{
			CheckBox chk = chkDivisas.next();
			if((Boolean)chk.getValue())
			{
				Valor divisa = (Valor)chk.getData();
				RegistrarSolicitudDivisaUI divisaUI = mapDenominaciones.get(chk);
				
				//List<DetalleDenominacion> detalleDenominaciones = mapDenominaciones.get(chk).getDenominaciones();
				if(divisaUI.getTotalDivisa().longValue() > 0)
				{
					DetalleMoneda detalleMoneda = new DetalleMoneda();
					detalleMoneda.setMoneda(divisa);
					detalleMoneda.setTotal(divisaUI.getTotalDivisa());
					detalleMoneda.setTotalBillete(new BigDecimal("0.0"));//FIXME
					detalleMoneda.setTotalMoneda(new BigDecimal("0.0"));//FIXME
					//FIXME obtener otros totales
					//detalleMoneda.setDetalleDenominaciones(detalleDens);
					detalleMoneda.setDetalleDenominaciones(new ArrayList<DetalleDenominacion>());
					divisaUI.asignarDetalleMoneda(detalleMoneda);
					destino.addDetalleMoneda(detalleMoneda);
				}
			}
		}
		
		//
		for (int i = 1; i < lytAtmsCasetera.getColumns(); i++) {
			for (int j = 1; j < lytAtmsCasetera.getRows(); j++) {
				VerticalLayout vLayout = (VerticalLayout) lytAtmsCasetera.getComponent(i, j);
				if(vLayout == null)
				{
					continue;
				}
				Casetera casetera = (Casetera) vLayout.getData();
				HorizontalLayout hLayout = (HorizontalLayout) vLayout.getComponent(1);
				ManejadorDenominacion2 manejadorDenominacion = (ManejadorDenominacion2) hLayout.getData();
				BigInteger cantidad = manejadorDenominacion.getCantidad();
				
				if(cantidad.intValue() > 0)
				{
					DetalleCasetera detalleCasetera = new DetalleCasetera();
					
					HorizontalLayout hLayoutObs = (HorizontalLayout) vLayout.getComponent(2);
					TextArea txtObservacion = (TextArea) hLayoutObs.getComponent(0);
					
					detalleCasetera.setCantidad(cantidad);
					detalleCasetera.setCasetera(casetera);
					detalleCasetera.setObservacion((String)txtObservacion.getValue());
					
					destino.addDetalleCasetera(detalleCasetera);
					
				}
				
				
				
			}
		}
		
		//return detalleMonedas;
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// tabDetalles
		tabDetalles = buildTabDetalles();
		mainLayout.addComponent(tabDetalles);
		mainLayout.setExpandRatio(tabDetalles, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private TabSheet buildTabDetalles() {
		// common part: create layout
		tabDetalles = new TabSheet();
		tabDetalles.setImmediate(true);
		tabDetalles.setWidth("100.0%");
		tabDetalles.setHeight("100.0%");
		
		// lytDetalles
		lytDetalles = buildLytDetalles();
		tabDetalles.addTab(lytDetalles, "Detalles", null);
		
		// lytAtms
		lytAtms = buildLytAtms();
		tabDetalles.addTab(lytAtms, "ATM", null);
		
		return tabDetalles;
	}

	@AutoGenerated
	private VerticalLayout buildLytDetalles() {
		// common part: create layout
		lytDetalles = new VerticalLayout();
		lytDetalles.setImmediate(false);
		lytDetalles.setWidth("100.0%");
		lytDetalles.setHeight("100.0%");
		lytDetalles.setMargin(false);
		lytDetalles.setSpacing(true);
		
		// pnlDivisas
		pnlDivisas = buildPnlDivisas();
		lytDetalles.addComponent(pnlDivisas);
		lytDetalles.setExpandRatio(pnlDivisas, 1.0f);
		
		return lytDetalles;
	}

	@AutoGenerated
	private Panel buildPnlDivisas() {
		// common part: create layout
		pnlDivisas = new Panel();
		pnlDivisas.setImmediate(false);
		pnlDivisas.setWidth("100.0%");
		pnlDivisas.setHeight("100.0%");
		
		// lytContenido
		lytContenido = buildLytContenido();
		pnlDivisas.setContent(lytContenido);
		
		return pnlDivisas;
	}

	@AutoGenerated
	private VerticalLayout buildLytContenido() {
		// common part: create layout
		lytContenido = new VerticalLayout();
		lytContenido.setImmediate(false);
		lytContenido.setWidth("100.0%");
		lytContenido.setHeight("100.0%");
		lytContenido.setMargin(false);
		lytContenido.setSpacing(true);
		
		// lytCheckDivisas
		lytCheckDivisas = new HorizontalLayout();
		lytCheckDivisas.setImmediate(false);
		lytCheckDivisas.setWidth("-1px");
		lytCheckDivisas.setHeight("-1px");
		lytCheckDivisas.setMargin(false);
		lytCheckDivisas.setSpacing(true);
		lytContenido.addComponent(lytCheckDivisas);
		lytContenido.setComponentAlignment(lytCheckDivisas, new Alignment(6));
		
		return lytContenido;
	}

	@AutoGenerated
	private VerticalLayout buildLytAtms() {
		// common part: create layout
		lytAtms = new VerticalLayout();
		lytAtms.setImmediate(false);
		lytAtms.setWidth("100.0%");
		lytAtms.setHeight("100.0%");
		lytAtms.setMargin(true);
		lytAtms.setSpacing(true);
		
		// pnlAtms
		pnlAtms = buildPnlAtms();
		lytAtms.addComponent(pnlAtms);
		lytAtms.setExpandRatio(pnlAtms, 1.0f);
		
		return lytAtms;
	}

	@AutoGenerated
	private Panel buildPnlAtms() {
		// common part: create layout
		pnlAtms = new Panel();
		pnlAtms.setImmediate(false);
		pnlAtms.setWidth("100.0%");
		pnlAtms.setHeight("100.0%");
		
		// lytPnlAtms
		lytPnlAtms = buildLytPnlAtms();
		pnlAtms.setContent(lytPnlAtms);
		
		return pnlAtms;
	}

	@AutoGenerated
	private VerticalLayout buildLytPnlAtms() {
		// common part: create layout
		lytPnlAtms = new VerticalLayout();
		lytPnlAtms.setImmediate(false);
		lytPnlAtms.setWidth("100.0%");
		lytPnlAtms.setHeight("100.0%");
		lytPnlAtms.setMargin(false);
		
		// lytAtmsCasetera
		lytAtmsCasetera = new GridLayout();
		lytAtmsCasetera.setImmediate(false);
		lytAtmsCasetera.setWidth("-1px");
		lytAtmsCasetera.setHeight("-1px");
		lytAtmsCasetera.setMargin(false);
		lytPnlAtms.addComponent(lytAtmsCasetera);
		
		// hlytTotales
		hlytTotales = new HorizontalLayout();
		hlytTotales.setImmediate(false);
		hlytTotales.setWidth("-1px");
		hlytTotales.setHeight("-1px");
		hlytTotales.setMargin(false);
		lytPnlAtms.addComponent(hlytTotales);
		lytPnlAtms.setComponentAlignment(hlytTotales, new Alignment(6));
		
		return lytPnlAtms;
	}

}
